package com.niit.gams.config;


import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

/*
 * shiro的配置类,其中声明三个对象：
 *   realm安全实体数据源：用自定义的UserRealm类来创建
 *   DefaultWebSecurityManager默认安全管理器：需要关联realm对象，在方法参数中传入realm对象的参数，用@Qualifier指定需要的realm实现类UserRealm方法名
 *   ShiroFilterFactoryBeanshiro过滤工厂对象：需要关联SecurityManager对象，同样在参数中传入该对象的参数，用@Qualifier指定需要的实现类方法名
 */
@Configuration
public class ShiroConfig {
  //创建自定义Realm对象
  @Bean
  public UserRealm userRealm() {
    return new UserRealm();
  }

  @Bean
  public DefaultWebSecurityManager securityManager(@Qualifier("userRealm") UserRealm userRealm) {
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
    securityManager.setRealm(userRealm);
    return securityManager;
  }

  @Bean
  public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager) {
    ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();
    filterFactoryBean.setSecurityManager(securityManager);
    /*
     shiro内置的过滤器:
        //认证过滤
        anon：无需认证就可以访问
        authc：必须认证了才能访问
        user：必须拥有记住我功能才能使用
        //授权过滤
        perms：拥有对某个资源的权限才能访问
        role：拥有某个角色权限才能访问
     */
    Map<String, String> filterMap = new LinkedHashMap<>();
    filterMap.put("/toLogin", "anon");
    filterMap.put("/css/**","anon");
    filterMap.put("/fonts/**","anon");
    filterMap.put("/img/**","anon");
    filterMap.put("/js/**","anon");
    filterMap.put("/singers","anon");
    //filterMap.put("/users/add", "perms[users:add]");
    //filterMap.put("/users/update", "perms[users:edit]");
    filterMap.put("/**", "authc");
    filterFactoryBean.setFilterChainDefinitionMap(filterMap);
    //设置登录的请求
    filterFactoryBean.setLoginUrl("/users/login");
    //filterFactoryBean.setSuccessUrl("/");
    //设置未授权返回的请求地址
    filterFactoryBean.setUnauthorizedUrl("/unauthor");
    return filterFactoryBean;
  }

  // 用来整合shiro和thymeleaf
  @Bean
  public ShiroDialect shiroDialect(){
    return new ShiroDialect();
  }

  /**
   *  开启shiro aop注解支持.否则@RequiresRoles等注解无法生效
   */
  @Bean
  public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){
    AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
    authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
    return authorizationAttributeSourceAdvisor;
  }

  /**
   * 自动创建代理
   */
  @Bean
  @ConditionalOnMissingBean
  public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
    DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
    advisorAutoProxyCreator.setProxyTargetClass(true);
    return advisorAutoProxyCreator;
  }
}
